/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.asportoonline.actions;

import java.io.IOException;
import java.sql.Time;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.asportoonline.business.beans.CategoriaManager;
import org.asportoonline.business.beans.ClienteManager;
import org.asportoonline.business.beans.LocaleManager;
import org.asportoonline.business.beans.ProdottoManager;
import org.asportoonline.business.delegates.CategoriaManagerDelegate;
import org.asportoonline.business.delegates.ClienteManagerDelegate;
import org.asportoonline.business.delegates.LocaleManagerDelegate;
import org.asportoonline.business.delegates.ProdottoManagerDelegate;
import org.asportoonline.entities.Cliente;
import org.asportoonline.entities.Indirizzo;
import org.asportoonline.entities.Locale;
import org.asportoonline.various.LocaleValidation;

/**
 *
 * @author fe
 */
public class LocaleAction extends HttpServlet {
    private LocaleManager lm = new LocaleManagerDelegate();
    private ClienteManager cm = new ClienteManagerDelegate();
    private ProdottoManager pm = new ProdottoManagerDelegate();
    private CategoriaManager catm = new CategoriaManagerDelegate();
    
    protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String s = request.getParameter("q").toString();
        
        if(s.equals("fetch_all_locality")) {
            request.setAttribute("localita", lm.recuperaTutteLeLocalita());
            getServletContext().getRequestDispatcher("/MainController?q=index2").forward(request, response);
        }
        
        else if(s.equals("base_search")) {
            String loc = request.getParameter("localita").toString();
            if(loc.equals("none")) {
                getServletContext().getRequestDispatcher("/MainController?q=index").forward(request, response);
            }
            else {
                List<Locale> ll = lm.cercaPerLocalita(loc);
                request.setAttribute("num_locali", ll.size());

                List<String> nomi_categorie = catm.recuperaNomiCategorie();
                request.setAttribute("nomi_categorie", nomi_categorie);
                
                int[] numero_categorie = null;
                if(nomi_categorie != null) {
                    numero_categorie = new int[nomi_categorie.size()];
                    for(int i=0; i<nomi_categorie.size(); i++) {
                        numero_categorie[i] = pm.numeroLocaliDiUnaLocalitaConProdottiDellaCategoria(nomi_categorie.get(i).toString(), loc);
                    }
                }
                request.setAttribute("numero_categorie", numero_categorie);
                getServletContext().getRequestDispatcher("/MainController?q=index2&mode=second_search&loc="+loc).forward(request, response);
            }
        }
        
        else if(s.equals("view_restaurants_by_locality")) {
            String loc = request.getParameter("loc").toString();
            List<Locale> lista = lm.cercaPerLocalita(loc);
            request.setAttribute("lista_locali", lista);
            request.setAttribute("num_locali", lista.size());            
            getServletContext().getRequestDispatcher("/MainController?q=view_results_search&mode=bylocality&loc="+loc).forward(request, response);
        }
        
        else if(s.equals("view_restaurants_by_category")) {
            String cat = request.getParameter("cat").toString();
            String loc = request.getParameter("localita").toString();
            //List<Locale> lista = pm.localiConProdottiDellaCategoria(cat);
            List<Locale> lista = pm.localiDiUnaLocalitaConProdottiDellaCategoria(cat, loc);
            request.setAttribute("lista_locali", lista);

            int num;
            if(lista==null || lista.isEmpty()) {
                num = 0;
            }
            else {
                num = lista.size();
            }
            request.setAttribute("num_locali", num);            
            getServletContext().getRequestDispatcher("/MainController?q=view_results_search&mode=bycategory&cat="+cat).forward(request, response);
        }
        
        else if(s.equals("register_restaurant_action")) {
            String res = verifica_registrazione(request);
            if(res.equals("OK")) {
                request.setAttribute("error", "Nuovo locale registrato correttamente!!!");
                getServletContext().getRequestDispatcher("/MainController?q=fetch_restaurants_data_action&ret=list_restaurants").forward(request, response);
            }
            else {
                request.setAttribute("error", res);
                getServletContext().getRequestDispatcher("/MainController?q=register_restaurant").forward(request, response);
            }
        }
        
        else if(s.equals("fetch_restaurants_data_action")) {
            String ret = request.getParameter("ret").toString();
            recupera_dati_locali(request);
            getServletContext().getRequestDispatcher("/MainController?q="+ret).forward(request, response);
        }

        else if(s.equals("fetch_restaurant_details_action")) {
            HttpServletRequest res = recupera_dati_di_un_locale(request);
            String ret = request.getParameter("ret").toString();
            String idlocale = request.getParameter("idlocale").toString();
            if(res == null) {       //teoricamente non fallisce mai!!
                request.setAttribute("error", "Errore nel recupero dei dati del locale con id="+idlocale);
                getServletContext().getRequestDispatcher("/MainController?q=index").forward(request, response);
            }
            else {
                if(ret.equals("restaurant_details")) {
                    Locale l = lm.cercaLocale(Integer.parseInt(idlocale));
                    request.setAttribute("prodotti", pm.cercaProdottiDelLocale(l));
                }
                getServletContext().getRequestDispatcher("/MainController?q="+ret).forward(request, response);
            }
        }

        else if(s.equals("modify_restaurant_action")) {
            String res = modifica_dati_locale(request);
            if(res.equals("OK")) {       
                getServletContext().getRequestDispatcher("/MainController?q=fetch_restaurants_data_action&ret=list_restaurants").forward(request, response);
            }
            else {
                request.setAttribute("error", res);
                String idlocale = request.getParameter("idlocale").toString();
                getServletContext().getRequestDispatcher("/MainController?q=fetch_restaurant_details_action&ret=modify_restaurant&idlocale="+idlocale).forward(request, response);
            }
        }
        
        else if(s.equals("delete_restaurant_action")) {
            int idlocale = Integer.parseInt(request.getParameter("idlocale").toString());
            Locale loc = lm.cercaLocale(idlocale);
            lm.eliminaLocale(loc);
            getServletContext().getRequestDispatcher("/MainController?q=fetch_restaurants_data_action&ret=list_restaurants").forward(request, response);            
        }
}
    
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        processRequest(request, response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        processRequest(request, response);
    }

    private String verifica_registrazione(HttpServletRequest request) {
        String nome = request.getParameter("nome").toString().trim();
        String via = request.getParameter("via").toString().trim();
        String cap = request.getParameter("cap").toString().trim();
        String citta = request.getParameter("citta").toString().trim();
        double latitudine = Double.parseDouble(request.getParameter("latitudine").toString());
        double longitudine = Double.parseDouble(request.getParameter("longitudine").toString());
        String telefono = request.getParameter("telefono").toString().trim();
        Indirizzo indirizzo = new Indirizzo();
        String piva = request.getParameter("piva").toString().trim();
        String email = request.getParameter("email").toString().trim();
        
        String prima_apertura = request.getParameter("prima_apertura").toString().trim();
        String prima_chiusura = request.getParameter("prima_chiusura").toString().trim();
        String apertura1;
        
        //dopo uso il parametro second_open  (checkbox)
        String seconda_apertura;// = request.getParameter("seconda_apertura").toString().trim();
        String seconda_chiusura;// = request.getParameter("seconda_chiusura").toString().trim();
        String apertura2 = null;
        
        String closed = request.getParameter("giorno_chiusura").toString();
        int giorno_chiusura;
        
        String distance = request.getParameter("distanza_massima").toString();
        int distanza_massima;
        
        String urlimmagine = request.getParameter("urlimmagine").toString().trim();

        /* CONTROLLI SUI CAMPI */
        //il nome del locale deve essere univoco
        if(nome.isEmpty()) {
            return "Inserire il nome del locale!!!";
        }
        else if(lm.cercaLocale(nome) != null) {
            return "Nome locale non disponbile!!!";
        }
        
        if(via.isEmpty() || cap.isEmpty() || citta.isEmpty()) {            
           return "Inserire tutti i campi dell'indirizzo!!!";            
        }
        else {
            indirizzo.setCap(cap);
            indirizzo.setCitta(citta);
            indirizzo.setVia(via);
            indirizzo.setLatitudine(latitudine);
            indirizzo.setLongitudine(longitudine);
        }
        
        //l'email deve essere valida
        if(!LocaleValidation.validateEmail(email)) {
            return "L'email inserita non e' corretta!!!";
        }        
        
        //controllo P.IVA.
        if(!LocaleValidation.validatePiva(piva)) {
            return "P.IVA. non corretta!!!";
        }
        
        //controllo l'orario della prima apertura
        //l'unico vincolo e' che l'apertura e la chiusura non possono avvenire nello stesso orario
        if(prima_apertura.equals(prima_chiusura)) {
            return "L'orario della prima apertura non e' corretto!!";
        }
        else {
            apertura1 = prima_apertura + " - " + prima_chiusura;
        }
        
        //controllo l'orario della seconda apertura
        // se viene inserito, non puo' accavallarsi all'oraio della prima apertura
        if(request.getParameter("second_open")!=null) {
            seconda_apertura = request.getParameter("seconda_apertura").toString().trim();
            seconda_chiusura = request.getParameter("seconda_chiusura").toString().trim();
            
            if(seconda_apertura.equals(seconda_chiusura)) {
                return "L'orario della seconda apertura non e' corretto!!";
            }
                        
            long tap1 = (Time.valueOf(prima_apertura+":00").getTime()+3600000);
            long tch1 = (Time.valueOf(prima_chiusura+":00").getTime()+3600000);
            long diff1;

            long tap2 = (Time.valueOf(seconda_apertura+":00").getTime()+3600000);
            long tch2 = (Time.valueOf(seconda_chiusura+":00").getTime()+3600000);
            long diff2;

            // dopo aver aggiunto 3600000 ho:
            // 00:00:00  -->  0
            // 23:59:59  -->  86399000
            // senza l'aggiunta dava problemi perche' risultava:
            // 00:00:00  -->  -3600000
            // 01:00:00  -->  0
            if(tap1 > tch1) {   //c'e' in mezzo il cambio di giorno
                diff1 = (tch1+86399000)-tap1;
            }
            else {
                diff1 = tch1 - tap1;
            }

            if(tap2 > tch2) {   //c'e' in mezzo il cambio di giorno
                diff2 = (tch2+86399000)-tap2;
            }
            else {
                diff2 = tch2 - tap2;
            }
                
            if(tap2>=tap1 && tap2<=tap1+diff1) {  //seconda_apertura tra prima_apertura e prima_chiusura
                return "L'orario della seconda apertura non deve sovrapporsi all'orario della prima apertura!!!";
            }
   
            if(tap2+diff2>=tap1 && tap2+diff2<=tap1+diff1) {  //seconda_chiusura tra prima_apertura e prima_chiusura
                return "L'orario della seconda apertura non deve sovrapporsi all'orario della prima apertura!!!";
            }

            if(tap2<=tap1 && tap2+diff2>=tap1+diff1) {  //primo orario completamente in mezzo al secondo orario
                return "L'orario della seconda apertura non deve sovrapporsi all'orario della prima apertura!!!";
            }
            
            if(seconda_apertura.equals(prima_apertura) || seconda_apertura.equals(prima_chiusura) || seconda_chiusura.equals(prima_apertura) || seconda_chiusura.equals(prima_chiusura)) {
                return "L'orario della seconda apertura non deve sovrapporsi all'orario della prima apertura!!!";
            }

            apertura2 = seconda_apertura + " - " + seconda_chiusura;
        }
        
        
        //controllo il giorno di chiusura
        if(closed.equals("none")) {
            return "Inserire il giorno di chiusura!!!";
        }
        else {
            try {
                giorno_chiusura = Integer.parseInt(closed);
            } catch(NumberFormatException ne) {     //non succede mai
                return "Giorno di chiusura non corretto!!!";
            }
        }
        
        //controllo la distanza massima di consegna
        if(distance.isEmpty()) {
            return "Inserire la distanza massima di consegna!!!";
        }
        else {
            try {
                distanza_massima = Integer.parseInt(distance);
            } catch(NumberFormatException nfe) {
                return "Distanza massima di consegna non corretta!!!";
            }   
            if(distanza_massima <= 0) {
                return "Distanza massima di consegna non valida!!!";
            }
        }
        
        
        /* SETTO I CAMPI DI LOCALE (ora sono tutti corretti) */
        Locale l = new Locale();
        
        l.setNome(nome);
        l.setEmail(email);
        l.setPrimaApertura(apertura1);
        l.setSecondaApertura(apertura2);        //se non e' settata e' null
        l.setDistanzaMassima(distanza_massima);
        l.setGiornoChiusura(giorno_chiusura);
        l.setPiva(piva);
        l.setIndirizzo(indirizzo);
        if(!telefono.isEmpty())     l.setTelefono(telefono);
        if(!urlimmagine.isEmpty())  l.setUrlimmagine(urlimmagine);
        
        HttpSession ses = request.getSession(false);
        if(ses == null) {       //teoricamente non fallisce mai!!
            return "Sessione non trovata!!";
        }
        
        Cliente proprietario = cm.cercaCliente(ses.getAttribute("username").toString());
        if(proprietario == null) {       //teoricamente non fallisce mai!!
            return "Proprietario non trovato!!";
        }
        
        l.setProprietario(proprietario);

        lm.inserisciLocale(l);
        
        return "OK";        
    }

    private void recupera_dati_locali(HttpServletRequest request) {
        HttpSession ses = request.getSession(false); //Se non c'è la sessione, NON ne crea una nuova!!!
        List<Locale> ll;
        
        if(ses == null) {  //teoricamente non fallisce mai
            ll = null;
        }
        
        Cliente c = cm.cercaCliente(ses.getAttribute("username").toString());
        ll = lm.recuperaLocaliVenditore(c);
        
        request.setAttribute("lista_locali", ll);
    }

    private HttpServletRequest recupera_dati_di_un_locale(HttpServletRequest request) {
        int idlocale = Integer.parseInt(request.getParameter("idlocale").toString());
        Locale l = lm.cercaLocale(idlocale);
        if(l==null) {
            return null;
        }
        
        HttpSession ses = request.getSession();
        Cliente c = null;
        if(ses.getAttribute("username")!=null) {
            c = cm.cercaCliente(ses.getAttribute("username").toString());
        }
        
        request.setAttribute("cliente", c);
        request.setAttribute("locale", l);
        
        return request;
    }

    private String modifica_dati_locale(HttpServletRequest request) {
        int idlocale = Integer.parseInt(request.getParameter("idlocale").toString());
        String nome = request.getParameter("nome").toString().trim();
        String telefono = request.getParameter("telefono").toString().trim();
        String email = request.getParameter("email").toString().trim();
        
        String prima_apertura = request.getParameter("prima_apertura").toString().trim();
        String prima_chiusura = request.getParameter("prima_chiusura").toString().trim();
        String apertura1;
        
        //dopo uso il parametro second_open  (checkbox)
        String seconda_apertura;// = request.getParameter("seconda_apertura").toString().trim();
        String seconda_chiusura;// = request.getParameter("seconda_chiusura").toString().trim();
        String apertura2 = null;        
        
        String distance = request.getParameter("distanza_massima").toString();
        int distanza_massima;
        
        String closed = request.getParameter("giorno_chiusura").toString();
        int giorno_chiusura;
        String urlimmagine = request.getParameter("urlimmagine").toString().trim();

        /* CONTROLLI SUI CAMPI */
        //il nome del locale deve essere univoco
        if(nome.isEmpty()) {
            return "Inserire il nome del locale!!!";
        }
        else if(!lm.cercaLocale(idlocale).getNome().equals(nome) && lm.cercaLocale(nome) != null) {
            return "Nome locale non disponbile!!!";
        }
                
        //l'email deve essere valida
        if(!LocaleValidation.validateEmail(email)) {
            return "L'email inserita non e' corretta!!!";
        }        
        
        //controllo l'orario della prima apertura
        //l'unico vincolo e' che l'apertura e la chiusura non possono avvenire nello stesso orario
        if(prima_apertura.equals(prima_chiusura)) {
            return "L'orario della prima apertura non e' corretto!!";
        }
        else {
            apertura1 = prima_apertura + " - " + prima_chiusura;
        }

        //controllo l'orario della seconda apertura
        // se viene inserito, non puo' accavallarsi all'oraio della prima apertura
        if(request.getParameter("second_open")!=null) {
            seconda_apertura = request.getParameter("seconda_apertura").toString().trim();
            seconda_chiusura = request.getParameter("seconda_chiusura").toString().trim();
            
            if(seconda_apertura.equals(seconda_chiusura)) {
                return "L'orario della seconda apertura non e' corretto!!";
            }
                        
            long tap1 = (Time.valueOf(prima_apertura+":00").getTime()+3600000);
            long tch1 = (Time.valueOf(prima_chiusura+":00").getTime()+3600000);
            long diff1;

            long tap2 = (Time.valueOf(seconda_apertura+":00").getTime()+3600000);
            long tch2 = (Time.valueOf(seconda_chiusura+":00").getTime()+3600000);
            long diff2;

            // dopo aver aggiunto 3600000 ho:
            // 00:00:00  -->  0
            // 23:59:59  -->  86399000
            // senza l'aggiunta dava problemi perche' risultava:
            // 00:00:00  -->  -3600000
            // 01:00:00  -->  0
            if(tap1 > tch1) {   //c'e' in mezzo il cambio di giorno
                diff1 = (tch1+86399000)-tap1;
            }
            else {
                diff1 = tch1 - tap1;
            }

            if(tap2 > tch2) {   //c'e' in mezzo il cambio di giorno
                diff2 = (tch2+86399000)-tap2;
            }
            else {
                diff2 = tch2 - tap2;
            }
                
            if(tap2>=tap1 && tap2<=tap1+diff1) {  //seconda_apertura tra prima_apertura e prima_chiusura
                return "L'orario della seconda apertura non deve sovrapporsi all'orario della prima apertura!!!";
            }
   
            if(tap2+diff2>=tap1 && tap2+diff2<=tap1+diff1) {  //seconda_chiusura tra prima_apertura e prima_chiusura
                return "L'orario della seconda apertura non deve sovrapporsi all'orario della prima apertura!!!";
            }

            if(tap2<=tap1 && tap2+diff2>=tap1+diff1) {  //primo orario completamente in mezzo al secondo orario
                return "L'orario della seconda apertura non deve sovrapporsi all'orario della prima apertura!!!";
            }
            
            if(seconda_apertura.equals(prima_apertura) || seconda_apertura.equals(prima_chiusura) || seconda_chiusura.equals(prima_apertura) || seconda_chiusura.equals(prima_chiusura)) {
                return "L'orario della seconda apertura non deve sovrapporsi all'orario della prima apertura!!!";
            }

            apertura2 = seconda_apertura + " - " + seconda_chiusura;
        }        
        
        //controllo il giorno di chiusura
        if(closed.equals("none")) {
            return "Inserire il giorno di chiusura!!!";
        }
        else {
            try {
                giorno_chiusura = Integer.parseInt(closed);
            } catch(NumberFormatException ne) {     //non succede mai
                return "Giorno di chiusura non corretto!!!";
            }
        }
        
        //controllo la distanza massima di consegna
        if(distance.isEmpty()) {
            return "Inserire la distanza massima di consegna!!!";
        }
        else {
            try {
                distanza_massima = Integer.parseInt(distance);
            } catch(NumberFormatException nfe) {
                return "Distanza massima di consegna non corretta!!!";
            }            
        }
                
        
        //controllo la distanza massima di consegna
        if(distance.isEmpty()) {
            return "Inserire la distanza massima di consegna!!!";
        }
        else {
            try {
                distanza_massima = Integer.parseInt(distance);
            } catch(NumberFormatException nfe) {
                return "Distanza massima di consegna non corretta!!!";
            }            
        }
                

        /* SETTO I CAMPI DI CLIENTE (ora sono tutti corretti) */
        Locale l = lm.cercaLocale(idlocale);
        
        l.setNome(nome);
        l.setEmail(email);
        l.setPrimaApertura(apertura1);
        l.setSecondaApertura(apertura2);
        l.setDistanzaMassima(distanza_massima);
        l.setGiornoChiusura(giorno_chiusura);
        l.setTelefono(telefono);
        l.setUrlimmagine(urlimmagine);
        
        HttpSession ses = request.getSession(false);
        if(ses == null) {       //teoricamente non fallisce mai!!
            return "Sessione non trovata!!";
        }
        
        lm.aggiornaLocale(l);
        
        return "OK";        
    }
     
}
